package rapidp2p.backend;

import java.net.*;
import java.io.*;

/**
 * updated
 * @author LF
 */
public class UDPServer_1 {
TCPServer tcpserver = new TCPServer();
    DatagramSocket listenerSocket;
    String lineDelimeter = "\n";
    String fieldDelimeter = ",";
    byte[] receiveData = new byte[2048];
    byte[] sendData = new byte[2048];
    DirectoryEntry[] mp3Entries = new DirectoryEntry[100];//to store mp3 entries
    //String sentence;
    int mp3Counter = 0;          //keep track of total of mp3Entries

    public void listenSocket() {
        try {//create DatagramSocket for UDP connection, bind its port for all connections
            listenerSocket = new DatagramSocket(9876);
            System.out.println("Server Started");
        } catch (SocketException e) {
            System.err.println("DatagramSocket exception: " + e);
            return;
        }

        //DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        String returnMessage = "";
        String searchResults = "";

        while (true) {
            returnMessage = "";
            searchResults = "";
            receiveData = new byte[2048];//reset 
            sendData = new byte[2048];  //reset
            try {
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                listenerSocket.receive(receivePacket);
                String sentence = new String(receivePacket.getData());  //from bytes to String
                InetAddress ipAddress = receivePacket.getAddress();//get incoming client's IP
                int port = receivePacket.getPort();                //get incoming client's port # 
                System.out.println("INCOMNING CLIENT MESSAGE " + ipAddress + "\n" + sentence);   //TEST: print entire incoming message
                String[] lines = sentence.split(lineDelimeter);   //split MESSAGE into [] of lines
                //each line represents single mp3 entry
                for (int i = 0; i < lines.length - 1; i++) {              //TEST: print LINES[]
                    System.out.println("Line" + i + "\t" + lines[i] + "\n");
                }

                String[] entryFields = new String[2];      //array to store field of each line - 3 fields of mp3 entry                               
                //String searchResults = "";

                for (int k = 0; k < lines.length - 1; k++) {
                    entryFields = lines[k].split(fieldDelimeter);
                    System.out.println("Line's length : " + (lines.length - 1));

                    //if ((lines.length-1) == 1) {
                    if (entryFields[0] != null) {
                        System.out.println("Got inside of Method Check\n");
                        if (entryFields[0].equals("search")) {//search for file and build a returnMessage with entries if found
                            System.out.println("GOT TO SEARCH PART");
                            System.out.println("Search for " + entryFields[1] + "\n");
                            searchResults = searchMP3(entryFields[1]);//return String for search
                            returnMessage = searchResults;
                        } else if (entryFields[0].equals("close")) {
                            removeClient(ipAddress);
                        } else if (entryFields[0].equals("download")) {
                            System.out.println("Download message reached server\n");
                            //send file request
                            //tcpserver.listenSocket("C:\\Users\\LF\\share\\50keepit.mp3");
                        } else {//must have at least 2 mp3Entries for this to work
                            mp3Entries[mp3Counter] = new DirectoryEntry(entryFields[0], entryFields[1], ipAddress.toString());
                            returnMessage += "Accepted : " + mp3Entries[mp3Counter].getFilename() + " SIZE: "
                                    + mp3Entries[mp3Counter].getFileSize() + " HOSTNAME: " + mp3Entries[mp3Counter].getHostname().toString() + "\n";
                            mp3Counter++;
                        }
                    }
                    entryFields[0] = entryFields[1] = "";
                }

                System.out.println("The Length of mp3 list is :" + (mp3Counter));//minus 1 since each mp3entry is followed by \n, results in additional line count

                //returnMessage += "--END OF LIST--\n";
                sendData = returnMessage.getBytes();//convert returnSentence to bytes
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ipAddress, port);

                lines = null;
                sentence = null;
                //returnMessage = null;
                //searchResults = null;

                try {
                    listenerSocket.send(sendPacket);
                    System.out.println("Packet sent\n");
                } catch (IOException e) {
                    System.err.println("Error sending UDP packet" + e);
                }
            } catch (IOException e) {
                System.err.println("listenerSocket.receive() problem : " + e);
                System.exit(-1);
            }
        }
    }

    public String searchMP3(String filename) {//return DirectoryEntry [] containng search results
        String returnEntries = "";
        //int count = 0;
        for (int m = 0; m < mp3Counter; m++) {
            String compareName = mp3Entries[m].getFilename();
            System.out.println("COMPARE NAME " + compareName + "\n");
            if (compareName.contains(filename)) {
                System.out.println("SUCCESS Filename match found for " + filename + "\n");
                returnEntries += mp3Entries[m].getFilename() + ","
                        + mp3Entries[m].getFileSize() + ","
                        + mp3Entries[m].getHostname() + "\n";
            } else {
                System.out.println("No Match Found \n");
            }
        }
        System.out.println("Return entries are:\n" + returnEntries);
        return returnEntries;//return search results
    }

    //removes mp3Entries associated with client with ipAddress - rather sets that entry to NULL for now
    public void removeClient(InetAddress ipAddress) {
        int length = mp3Entries.length;
        System.out.println("ipAddress is " + ipAddress);
        for (int j = 0; j < (length - 1); j++) {
            System.out.println("mp3's InetAddress is " + mp3Entries[j].getHostname().toString());
            if (mp3Entries[j].getHostname().equals(ipAddress)) {
                System.out.println("Removing " + mp3Entries[j].getFilename() + " "
                        + mp3Entries[j].getFileSize() + " " + mp3Entries[j].getHostname() + "\n");
                mp3Entries[j] = new DirectoryEntry("", "", null);
            }
//            if(mp3Entries.length-1 == j){
//                break;
//            }
        }
        System.out.println("Array After Removal\n");
        if (mp3Entries.length < 1) {
            System.out.println("Array Empty\n");
        } else {
            for (int n = 0; n < mp3Entries.length - 1; n++) {
                if ((mp3Entries[n].getFilename()) != null) {
                    System.out.println("RECORD " + mp3Entries[n].getFilename() + " "
                            + mp3Entries[n].getFileSize() + " " + mp3Entries[n].getHostname() + "\n");
                }
            }
        }
    }

    public static void main(String[] args) {
        //DatagramSocket listenerSocket;
        //DirectoryServer ds = new DirectoryServer();
        //ds.start();                                    
        //starts new Thread, since main class extends Thread
        UDPServer_1 udpServer = new UDPServer_1();
        udpServer.listenSocket();

    }
}
